package
{
import flash.display.Sprite;
import flash.utils.getTimer;

/**
 * 思路：为了算出比较真实的值，有N组随机值则累加N组随机值除以N  每次累加的数组会比较平均
 * @author RockyChen
 * $Id: TestCalc.as 2 2012-05-17 10:10:03Z cgslendy@gmail.com $
 */
public class TestCalc extends Sprite
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	/**
	 * Constructs a new <code>TestCalc</code> instance.
	 * 
	 */
	public function TestCalc()
	{
		//testCalc
		var len:int = calFuncArr.length;
		for (var i:int = 0; i < len; i++)
		{
			startCalc(i);
		}
	}
	
	//==========================================================================
	//  Variables
	//==========================================================================
	private var resultObj:Object = {};
	private const COUNT:int = 1000000;
	private const COUNTINDEX:int = 7;
	/**
	 * 累加权值
	 */	
	private const COUNTWEIGHT:int = int(COUNTINDEX*COUNTINDEX/5) + 1;
	/**
	 * 计算函数
	 */	
	private var calFuncArr:Array = [func5, calFunN_1, calFunN_2, calFunN_3];
	
	//==========================================================================
	//  Methods
	//==========================================================================
	/**
	 * 测试函数
	 * @param calType 0测试 1算法1 2 算法2
	 * 
	 */	
	private function startCalc(calType:int):void
	{
		resultObj = {};
		var index:int;
		var tmp:int;
		var time:int = getTimer();
		for (var i:int = 1; i <= COUNT; i++)
		{
			index = calFuncArr[calType]();
			tmp = resultObj[index];
			!tmp && (tmp = 0);
			tmp += 1;
			resultObj[index] = tmp;
		}
		
		var calNum:int = calType ? COUNTINDEX : 5;
		var logStr:String = "";
		var totalNum:Number = 0;
		var perNum:Number = 0;
		for (var props:* in resultObj)
		{
			perNum = 1 - resultObj[props]/(COUNT/calNum);
			logStr += props + ": 个数" + resultObj[props] + " 误差" + perNum + "\n";
			totalNum += (perNum > 0) ? perNum : -perNum;
		}
		logStr += "平均误差:" + int(totalNum/calNum*10000)/10000 + "\n";
		logStr += "耗时：" + (getTimer() - time) + "\n";
		trace(logStr);
	}
	
	/**
	 * 随机数相加求余 权值为COUNTWEIGHT
	 * @param count
	 * @return 
	 * 
	 */	
	private function calFunN_1(count:int = COUNTINDEX):int
	{
		var index:int;
		for (var i:int = 0; i < COUNTWEIGHT; i++)
		{
			index += func5();
		}
		return index % count;
	}
	
	/**
	 * 随机数相乘求余  权值3 即累积三次
	 * @param count
	 * @return 
	 * 
	 */	
	private function calFunN_2(count:int = COUNTINDEX):int
	{
		var index:int = getFunN();
		index += getFunN();
		index += getFunN();
		return index % count;
	}
	
	/**
	 * 随机数相乘并做条件递归
	 * @param count
	 * @return 
	 * 
	 */	
	private function calFunN_3(count:int = COUNTINDEX):int
	{
		var index:int = getFunN();
		while (index >= COUNTINDEX*3)
		{
			index = getFunN();
		}
		return int(index/3);
		/*if (index >= COUNTINDEX*3)
		{
			index = calFunN_3();
		}
		else
		{
			index = int(index/3);
		}
		return index;*/
	}
	
	/**
	 * 获取求N的函数表达值
	 * @return 
	 * 
	 */	
	private function getFunN():int
	{
		var count:int = int(Math.log(COUNTINDEX*3)/Math.log(5));
		var index:int = func5();
		for (var i:int = 0; i < count; i++)
		{
			index += Math.pow(5, i+1)*func5();
		}
		return index;
	}
	
	private function func5():int
	{
		return int(Math.random()*5*10/10);
	}
}
}